<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script type="text/javascript">
        // 源数据
        let person = {
            name: '张三',
            age: 18
        }

        // vue2响应式原理
        // let p = {}
        // Object.defineProperty(p,'name',{
        //     configurable: true,
        //     // 读取name时调用
        //     get() {
        //         return person.name
        //     },
        //     // 修改name时调用
        //     set(value) {
        //         console.log('有人修改了name属性被我发现了,我要去更新界面')
        //         person.name = value
        //     }
        // })
        // Object.defineProperty(p,'age',{
        //     get() {
        //         return person.age
        //     },
        //     set(value) {
        //         console.log('有人修改了age属性被我发现了,我要去更新界面')
        //         person.age = value
        //     }
        // })

        // vue3响应式原理  Proxy是代理对象  Reflect是反射对象
        /** 
         * 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写，属性的添加，属性的删除
         * 通过Reflect(反射):对源对象的属性进行操作
        */
        const p = new Proxy(person, {
            // 读取
            get(target, propName) {
                console.log(`有人读取了p身上的${propName}属性`, target, propName) // target就是person源对象,propName是属性名
                // return target[propName]
                return Reflect.get(target, propName)
            },
            // 新增/修改
            set(target, propName, value) {
                console.log(`有人修改了p身上的${propName}属性,我要去更新页面了`)
                // target[propName] = value
                Reflect.set(target, propName, value)
            },
            // 删除
            deleteProperty(target, propName) {
                console.log(`有人删除了p身上的${propName}属性,我要去更新页面了`)
                // return delete target[propName]
                return Reflect.deleteProperty(target, propName)
            }
        })

        let obj = { a: 1, b: 2 }
        // 通过Object.defineProperty去操作
        // try {
        //     Object.defineProperty(obj, 'c', {
        //         get() {
        //             return 3
        //         }
        //     })
        //     Object.defineProperty(obj, 'c', {
        //         get() {
        //             return 34
        //         }
        //     })
        // } catch (error) {
        //     console.log(err)
        // }

        // 通过Reflect.defineProperty去操作
        const x1 = Reflect.defineProperty(obj, 'c', {
            get() {
                return 3
            }
        })
        console.log(x1)

        const x2 = Reflect.defineProperty(obj, 'c', {
            get() {
                return 3
            }
        })
        if (x2) {
            console.log('某某某操作成功了!')
        } else {
            console.log('某某某操作失败了!')
        }
        // console.log('@@@')
    </script>
</body>

</html>